import com.rongyi.transfer.mapper.TransferMapper;
import com.rongyi.transfer.vo.InsertVo;
import com.rongyi.transfer.vo.UpdateVo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class TransferService {
    @Resource
    private TransferMapper transferMapper;

    @Autowired
    private ApplicationProperties properties;

	// 第一个定制点（其实这部分可能会使用到的项目应该也不少，可以抽取出表名为配置）
	// 发送者一张表的数据，接收者两张表接收——需要额外新增
    public void extraInsert(InsertVo insertVo) {
        if (insertVo.getTableName().equals("ctlm01")) {
        	// 如果是c01表需要额外新增数据到c11表
            insertVo.setTableName("ctlm11");
            insertVo.setShortName("c11");
        } else { // ctlm02
        	// 如果是c02表需要额外新增数据到c12表
            insertVo.setTableName("ctlm12");
            insertVo.setShortName("c12");
        }
        // 判断表中是否已存在该数据（id判断）
        Integer count = transferMapper.extraCheck(insertVo);
        // 存在则删除
        if (count > 0) {
            transferMapper.extraDelete(insertVo);
        }
        // 新增数据
        transferMapper.extraInsert(insertVo);
    }

    public void moveData(String shortName) throws SQLException {
        // 创建变量保存表名
        String tableName = "";
        // 表名简称不为空时，通过表名简称前缀确定表名
        if (shortName == null || "".equals(shortName)) {
            // 表名简称为空直接返回
//            return "表名不能为空";
            System.out.println("表名不能为空");
        }
        // 表名拼接
        if (shortName.contains("c")) {
            tableName = shortName.replace("c", "ctlm");
        } else if (shortName.contains("i")) {
            tableName = shortName.replace("i", "inv");
        } else if (shortName.contains("w")) {
            tableName = shortName.replace("w", "weight");
        }
        // 表名不为空时才可进行数据转移操作
        if (tableName == null || "".equals(tableName)) {
            // 表名为空说明表名简称前缀无法识别
//            return "无法识别表";
            System.out.println("无法识别表");
        } else {
            move(tableName, shortName);
        }
        // 正常执行完成返回成功消息
        System.out.println(shortName + "数据转移完毕");
    }

	// 接收到表全名、简称，迁移数据
    private void move(String tableName, String shortName) throws SQLException {
        // 建立发送者连接
        Connection conSend = DriverManager.getConnection(properties.getSendUrl(), properties.getSendName(), properties.getSendPassword());
        Statement stmtSend = conSend.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
        // 创建变量保存查询sql
        String sql = properties.getSendSql();
        // 拼接
        sql = sql.replace("tableName", tableName);
        sql = sql.replace("shortName", shortName);
        try {
            // 通过拼接好的sql查询数据并保存到结果集
            ResultSet send = stmtSend.executeQuery(sql);
            if (send == null) {
                // 结果集为空说明没有新数据，不进行后续操作
//                return "null";
                System.out.println("没有需要进行迁移的数据");
                return;
            }
            // 建立接收者连接
            Connection conAccept = DriverManager.getConnection(properties.getAcceptUrl(), properties.getAcceptName(), properties.getAcceptPassword());
            Statement stmtAccept = conAccept.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
            // 定位接收表
            ResultSet accept = stmtAccept.executeQuery("select * from " + tableName);
            // 遍历发送者结果集
            while (send.next()) {
                // 开启新增
                accept.moveToInsertRow();
                // 获取当前表结构
                ResultSetMetaData metaData = send.getMetaData();
                // 通过表结构字段数遍历并设置当前行数据
                for (int i = 1; i <= metaData.getColumnCount(); i++) {
                    accept.updateString(metaData.getColumnLabel(i), send.getString(i));
                }
                // 保存新增内容
                accept.insertRow();
                // 创建column保存需要修改的字段名
                String column = properties.getUpdateColumn();
                column = column.replace("shortName", shortName);
                // 修改发送者表需要的字段数据
                send.updateString(column, properties.getUpdateString());
                send.updateRow();
            }
            // 有异常时抛出
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }

	// 第二个定制点：数据源获取数据多表联查获取，发送者（在这里是接收者）比数据源表字段多
	// 这个处理没有想到很好的代码抽取办法，所以在控制器（controller）层进行了表名判断走不同的方法
	// 有兴趣的码友可以抽取一下看看，可行希望能告知一声（相互学习！）
    public void moveCustom(String shortName) throws SQLException {
        // 创建变量保存表名
        String tableName = "";
        // 表名简称不为空时，通过表名简称前缀确定表名
        if (shortName == null || "".equals(shortName)) {
            // 表名简称为空直接返回
//            return "表名不能为空";
            System.out.println("表名不能为空");
        }
        if (shortName.contains("c")) {
            tableName = shortName.replace("c", "ctlm");
        } else if (shortName.contains("i")) {
            tableName = shortName.replace("i", "inv");
        } else if (shortName.contains("w")) {
            tableName = shortName.replace("w", "weight");
        }
        // 表名不为空时才可进行数据转移操作
        if (tableName == null || "".equals(tableName)) {
            // 表名为空说明表名简称前缀无法识别
//            return "无法识别表";
            System.out.println("无法识别表");
        }
        // 建立发送者连接
        Connection conSend = DriverManager.getConnection(properties.getSendUrl(), properties.getSendName(), properties.getSendPassword());
        Statement stmtSend = conSend.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
        // 创建变量保存查询sql
        String sql = properties.getSendSql();
        // 拼接
        sql = sql.replace("tableName", tableName);
        sql = sql.replace("shortName", shortName);
        try {
            // 通过拼接好的sql查询数据并保存到结果集
            ResultSet send = stmtSend.executeQuery(sql);
            if (send == null) {
                // 结果集为空说明没有新数据，不进行后续操作
//                return "null";
                System.out.println("没有需要进行迁移的数据");
            }
            // 建立接收者连接
            Connection conAccept = DriverManager.getConnection(properties.getAcceptUrl(), properties.getAcceptName(), properties.getAcceptPassword());
            Statement stmtAccept = conAccept.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
            // 定位接收表
            ResultSet accept = stmtAccept.executeQuery("select * from " + tableName);
            // 遍历发送者结果集
            while (send.next()) {
                // 开启新增
                accept.moveToInsertRow();
                // 获取当前表结构
                ResultSetMetaData metaData = send.getMetaData();
                // 通过表结构字段数遍历并设置当前行数据
                for (int i = 1; i <= metaData.getColumnCount(); i++) {
                    accept.updateString(metaData.getColumnLabel(i), send.getString(i));
                }
                // 保存新增内容
                accept.insertRow();
                // 创建column保存需要修改的字段名
                String column = properties.getUpdateColumn();
                column = column.replace("shortName", shortName);
                // 修改发送者表需要的字段数据
                send.updateString(column, properties.getUpdateString());
                send.updateRow();
                // 额外添加到表c202或c209
                if (shortName.equals("c511") || shortName.equals("c512")) {
                    InsertVo insertVo = new InsertVo();
                    insertVo.setTableName(tableName);
                    insertVo.setShortName(shortName);
                    for (int i = 1; i <= metaData.getColumnCount(); i++) {
                        // 获取到相应的两个字段数据
                        if (metaData.getColumnLabel(i).equals(shortName + "_id_supp")) {
                            insertVo.setIdSupp(send.getString(i));
                        }
                        if (metaData.getColumnLabel(i).equals(shortName + "_var_supp")) {
                            insertVo.setVarSupp(send.getString(i));
                        }
                    }
                    extraInsert(insertVo);
                }
            }
            // 有异常时抛出
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
        // 正常执行完成返回成功消息
        System.out.println(shortName + "数据转移完毕");
    }
}
